package com.cwd.arm.domain.repository.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.cwd.arm.common.enums.ErrorEnum;
import com.cwd.arm.common.exception.ArmException;
import com.cwd.arm.domain.entity.ProjectEntity;
import com.cwd.arm.domain.entity.ReceiveNodeEntity;
import com.cwd.arm.domain.entity.TaxEntity;
import com.cwd.arm.domain.repository.ProjectRepository;
import com.cwd.arm.domain.repository.ReceiveNodeRepository;
import com.cwd.arm.infrastructure.dao.ReceiveNodeDao;
import com.cwd.arm.infrastructure.dao.TaxDao;
import com.cwd.arm.infrastructure.po.ReceiveNodePo;
import com.cwd.arm.infrastructure.po.TaxPo;
import com.cwd.arm.infrastructure.query.TaxDaoQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
* Description:收款节点
* Created on 2021年11月16日
* @author  yan
*/
@Repository
public class ReceiveNodeRepositoryImpl implements ReceiveNodeRepository{

    @Autowired
    private ReceiveNodeDao dao;

    @Autowired
    private TaxDao taxDao;

    @Autowired
    private ProjectRepository projectRepository;

    @Override
    public Long save(ReceiveNodeEntity receiveNodeEntity) {
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(receiveNodeEntity.getProjectId());
        ReceiveNodePo receiveNodePo = convertToReceiveNodePo(receiveNodeEntity);
        dao.save(receiveNodePo);
        List<ReceiveNodeEntity> receiveNodeEntityList =  Arrays.asList(receiveNodeEntity);
        projectRepository.addNode(projectEntity,receiveNodeEntityList);
        return receiveNodePo.getId();
    }

    @Override
    public void save(List<ReceiveNodeEntity> receiveNodeEntityList) {
        receiveNodeEntityList = receiveNodeEntityList.stream().sorted(Comparator.comparing(ReceiveNodeEntity::getEndDate))
                .sorted().collect(Collectors.toList());
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(receiveNodeEntityList.get(0).getProjectId());
        save(receiveNodeEntityList, projectEntity);
    }

    private void save(List<ReceiveNodeEntity> receiveNodeEntityList, ProjectEntity projectEntity) {
        dao.saveBatch(convertToReceiveNodePoList(receiveNodeEntityList));
        projectRepository.addNode(projectEntity,receiveNodeEntityList);
    }

    @Override
    public void save(ProjectEntity projectEntity, List<ReceiveNodeEntity> entityList) {
        save(entityList,projectEntity);
    }

    @Override
    public void update(ReceiveNodeEntity receiveNodeEntity) {
        ReceiveNodeEntity oldReceiveNodeEntity = buildReceiveNodeEntity(receiveNodeEntity.getId());
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(oldReceiveNodeEntity.getProjectId());
        dao.updateById(convertToReceiveNodePo(receiveNodeEntity));
        projectRepository.updateNode(projectEntity,oldReceiveNodeEntity,receiveNodeEntity);
    }

    @Override
    public void del(Long id) {
        ReceiveNodeEntity entity = buildReceiveNodeEntity(id);
        TaxDaoQuery taxDaoQuery = new TaxDaoQuery();
        taxDaoQuery.setReceiveNodeId(id);
        List<TaxPo> taxPoList = taxDao.selectByQuery(taxDaoQuery);
        if(CollectionUtils.isEmpty(taxPoList)){
            dao.removeById(id);
        }else{
            throw new ArmException(ErrorEnum.VAILD_ERROR,"该节点下有开票记录，不可以删除");
        }
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(entity.getProjectId());
        projectRepository.delNode(projectEntity,entity);
    }

    @Override
    public ReceiveNodeEntity selectById(Long id) {
        return buildReceiveNodeEntity(id);
    }

    @Override
    public void addTax(ReceiveNodeEntity receiveNodeEntity,TaxEntity taxEntity) {
        receiveNodeEntity.addTax(taxEntity);
        ReceiveNodeEntity oldReceiveNodeEntity = buildReceiveNodeEntity(receiveNodeEntity.getId());
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(oldReceiveNodeEntity.getProjectId());
        projectRepository.updateNode(projectEntity,oldReceiveNodeEntity,receiveNodeEntity);
    }

    @Override
    public void updateTax(ReceiveNodeEntity receiveNodeEntity, TaxEntity oldTaxEntity, TaxEntity newTaxEntity) {
        receiveNodeEntity.updateTax(oldTaxEntity,newTaxEntity);
        update(receiveNodeEntity);
    }

    @Override
    public void delTax(ReceiveNodeEntity receiveNodeEntity, TaxEntity taxEntity) {
        ReceiveNodeEntity oldReceiveNodeEntity = buildReceiveNodeEntity(receiveNodeEntity.getId());
        receiveNodeEntity.delTax(taxEntity);
        ProjectEntity projectEntity = projectRepository.buildProjectEntity(oldReceiveNodeEntity.getProjectId());
        projectRepository.updateNode(projectEntity,oldReceiveNodeEntity,receiveNodeEntity);
    }

    @Override
    public ReceiveNodeEntity buildReceiveNodeEntity(Long id) {
        ReceiveNodeEntity entity = new ReceiveNodeEntity();
        ReceiveNodePo receiveNodePo = dao.getById(id);
        BeanUtils.copyProperties(receiveNodePo,entity);
        return entity;
    }

    private ReceiveNodePo convertToReceiveNodePo(ReceiveNodeEntity entity){
        ReceiveNodePo po = new ReceiveNodePo();
        BeanUtils.copyProperties(entity,po);
        return po;
    }

    private List<ReceiveNodePo> convertToReceiveNodePoList(List<ReceiveNodeEntity> entityList){
        return entityList.stream().map(entity->convertToReceiveNodePo(entity)).collect(Collectors.toList());
    }

}
